package api

import (
	"fmt"
	"net/http"
	"spam3uk/internal/models"
	"spam3uk/internal/scraper"
	"spam3uk/internal/storage"
	"strconv"
	"strings"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/sirupsen/logrus"
)

// VehicleHandler 车辆API处理器
type VehicleHandler struct {
	storage storage.VehicleStorage
	logger  *logrus.Logger
    version string
}

// NewVehicleHandler 创建车辆API处理器
func NewVehicleHandler(storage storage.VehicleStorage, logger *logrus.Logger, version string) *VehicleHandler {
	return &VehicleHandler{
		storage: storage,
		logger:  logger,
        version: version,
	}
}

// GetAllCars 获取所有汽车信息
// @Summary 获取所有汽车信息
// @Description 获取所有汽车信息，支持Ford分类筛选和分页
// @Tags vehicles
// @Produce json
// @Param vehicle_category query string false "Ford车辆分类" Enums(hybrid_electric, suv_crossovers, performance, people_movers)
// @Param vehicle_type query string false "具体车辆类型"
// @Param make query string false "品牌"
// @Param model query string false "车型"
// @Param min_price query number false "最低价格"
// @Param max_price query number false "最高价格"
// @Param fuel_type query string false "燃料类型"
// @Param page query int false "页码" default(1)
// @Param page_size query int false "每页数量" default(10)
// @Success 200 {object} models.VehicleResponse
// @Router /api/get_all_cars [get]
func (h *VehicleHandler) GetAllCars(c *gin.Context) {
	h.logger.Info("Getting all cars request")

	// 解析查询参数
	filter := &models.VehicleFilter{}
	if err := c.ShouldBindQuery(filter); err != nil {
		h.logger.WithError(err).Error("Failed to bind query parameters")
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "Invalid query parameters: " + err.Error(),
			"data":    nil,
		})
		return
	}

	// 设置默认分页参数
	if filter.Page <= 0 {
		filter.Page = 1
	}
	if filter.PageSize <= 0 {
		filter.PageSize = 10
	}

	h.logger.WithFields(logrus.Fields{
		"filter": filter,
	}).Info("Processing get all cars request")

	// 从存储获取数据
	vehicles, total, err := h.storage.GetAllCars(filter)
	if err != nil {
		h.logger.WithError(err).Error("Failed to get vehicles from storage")
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    500,
			"message": "Failed to get vehicles: " + err.Error(),
			"data":    nil,
		})
		return
	}

	// 返回响应
	response := models.VehicleResponse{
		Code:    200,
		Message: "Success",
		Data:    vehicles,
		Total:   total,
	}

	h.logger.WithFields(logrus.Fields{
		"total_count": total,
		"page":        filter.Page,
		"page_size":   filter.PageSize,
	}).Info("Successfully retrieved vehicles")

	c.JSON(http.StatusOK, response)
}

// GetCarByID 根据ID获取汽车信息
// @Summary 根据ID获取汽车信息
// @Description 根据ID获取特定汽车的详细信息
// @Tags vehicles
// @Produce json
// @Param id path int true "车辆ID"
// @Success 200 {object} models.VehicleInfo
// @Router /api/cars/{id} [get]
func (h *VehicleHandler) GetCarByID(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 32)
	if err != nil {
		h.logger.WithError(err).Error("Invalid car ID")
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "Invalid car ID",
			"data":    nil,
		})
		return
	}

	vehicle, err := h.storage.GetByID(uint(id))
	if err != nil {
		h.logger.WithError(err).Error("Failed to get vehicle by ID")
		c.JSON(http.StatusNotFound, gin.H{
			"code":    404,
			"message": "Vehicle not found",
			"data":    nil,
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"code":    200,
		"message": "Success",
		"data":    vehicle,
	})
}

// HealthCheck 健康检查
// @Summary 健康检查
// @Description 检查服务是否正常运行
// @Tags system
// @Produce json
// @Success 200 {object} map[string]interface{}
// @Router /health [get]
func (h *VehicleHandler) HealthCheck(c *gin.Context) {
	c.JSON(http.StatusOK, gin.H{
		"status":    "ok",
		"service":   "SPAM3-UK",
        "version":   h.version,
        "timestamp": time.Now().Format(time.RFC3339),
	})
}

// GetFordCategories 获取Ford车辆分类信息
// @Summary 获取Ford车辆分类信息
// @Description 获取Ford UK网站的车辆分类信息和预期数量
// @Tags vehicles
// @Produce json
// @Success 200 {object} map[string]interface{}
// @Router /api/categories [get]
func (h *VehicleHandler) GetFordCategories(c *gin.Context) {
	categories := models.GetFordCategories()

	// 获取当前数据库中的统计信息
	stats, err := h.storage.GetCategoryStats()
	if err != nil {
		h.logger.WithError(err).Error("Failed to get category statistics")
		// 如果获取统计失败，仍然返回基本分类信息
		stats = make(map[string]int64)
	}

	// 添加实际统计数据
	for i := range categories {
		categories[i].Description = fmt.Sprintf("%s (预期: %d辆, 当前: %d辆)",
			categories[i].Description,
			categories[i].ExpectedCount,
			stats[categories[i].Category])
	}

	c.JSON(http.StatusOK, gin.H{
		"code":    200,
		"message": "Success",
		"data":    categories,
		"stats":   stats,
	})
}

// GetVehiclesByCategory 根据分类获取车辆
// @Summary 根据Ford分类获取车辆
// @Description 根据Ford分类获取该分类下的所有车辆
// @Tags vehicles
// @Produce json
// @Param category path string true "车辆分类" Enums(hybrid_electric, suv_crossovers, performance, people_movers)
// @Success 200 {object} models.VehicleResponse
// @Router /api/categories/{category}/vehicles [get]
func (h *VehicleHandler) GetVehiclesByCategory(c *gin.Context) {
	category := c.Param("category")

	h.logger.WithField("category", category).Info("Getting vehicles by category")

	vehicles, err := h.storage.GetByCategory(category)
	if err != nil {
		h.logger.WithError(err).Error("Failed to get vehicles by category")
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    500,
			"message": "Failed to get vehicles: " + err.Error(),
			"data":    nil,
		})
		return
	}

	response := models.VehicleResponse{
		Code:    200,
		Message: "Success",
		Data:    vehicles,
		Total:   int64(len(vehicles)),
	}

	h.logger.WithFields(logrus.Fields{
		"category": category,
		"count":    len(vehicles),
	}).Info("Successfully retrieved vehicles by category")

	c.JSON(http.StatusOK, response)
}

// GetTrims 获取指定model的trim信息
// @Summary 获取车型trim信息
// @Description 根据model名称获取该车型的所有trim配置信息
// @Tags trims
// @Produce json
// @Param model query string true "车型名称"
// @Success 200 {object} models.TrimResponse
// @Router /api/get_trims [get]
func (h *VehicleHandler) GetTrims(c *gin.Context) {
	modelName := c.Query("model")
	if modelName == "" {
		h.logger.Error("Model parameter is required")
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "Model parameter is required",
			"data":    nil,
		})
		return
	}

	h.logger.WithField("model", modelName).Info("Getting trims for model")

	// 获取车型的detail_url
	detailURL, err := h.storage.GetVehicleDetailURL(modelName)
	if err != nil {
		h.logger.WithError(err).WithField("model", modelName).Error("Failed to get vehicle detail URL")
		c.JSON(http.StatusNotFound, gin.H{
			"code":    404,
			"message": fmt.Sprintf("Model '%s' not found", modelName),
			"data":    nil,
		})
		return
	}

	// 获取trim信息
	trims, err := h.storage.GetTrimsWithSpecs(modelName)
	if err != nil {
		h.logger.WithError(err).WithField("model", modelName).Error("Failed to get trims")
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    500,
			"message": "Failed to get trims: " + err.Error(),
			"data":    nil,
		})
		return
	}

	response := models.TrimResponse{
		ModelName:  modelName,
		DetailURL:  detailURL,
		Trims:      trims,
		TotalTrims: len(trims),
		ScrapedAt:  time.Now(),
	}

	// 如果没有找到trim数据，提示需要抓取
	if len(trims) == 0 {
		response.Message = fmt.Sprintf("No trim data found for model '%s'. Please scrape the data first.", modelName)
		h.logger.WithField("model", modelName).Warn("No trim data found")
	} else {
		response.Message = "Success"
		h.logger.WithFields(logrus.Fields{
			"model":       modelName,
			"trims_count": len(trims),
		}).Info("Successfully retrieved trims")
	}

	c.JSON(http.StatusOK, response)
}

// ScrapeTrims 抓取指定model的trim信息
// @Summary 抓取车型trim信息
// @Description 根据model名称抓取该车型的所有trim配置信息
// @Tags trims
// @Produce json
// @Param model query string true "车型名称"
// @Success 200 {object} gin.H
// @Router /api/scrape_trims [post]
func (h *VehicleHandler) ScrapeTrims(c *gin.Context) {
	modelName := c.Query("model")
	if modelName == "" {
		h.logger.Error("Model parameter is required")
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "Model parameter is required",
			"data":    nil,
		})
		return
	}

	h.logger.WithField("model", modelName).Info("Starting trim scraping")

    // 使用真实抓取器
    ts := scraper.NewTrimScraper(h.storage, h.logger)
    err := ts.ScrapeTrims(modelName)

	if err != nil {
		h.logger.WithError(err).WithField("model", modelName).Error("Failed to scrape trims")
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    500,
			"message": "Failed to scrape trims: " + err.Error(),
			"data":    nil,
		})
		return
	}

	// 获取抓取结果
	trims, err := h.storage.GetTrimsWithSpecs(modelName)
	if err != nil {
		h.logger.WithError(err).Error("Failed to get scraped trims")
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":    500,
			"message": "Failed to get scraped trims: " + err.Error(),
			"data":    nil,
		})
		return
	}

	h.logger.WithFields(logrus.Fields{
		"model":       modelName,
		"trims_count": len(trims),
	}).Info("Successfully scraped trims")

	c.JSON(http.StatusOK, gin.H{
		"code":    200,
		"message": fmt.Sprintf("Successfully scraped %d trims for model '%s'", len(trims), modelName),
		"data": gin.H{
			"model_name":  modelName,
			"trims_count": len(trims),
			"trims":       trims,
			"scraped_at":  time.Now(),
		},
	})
}

// ScrapeAllVehicles 抓取官网车辆清单（Cars/Vans）并入库
// @Summary 抓取官网车辆清单
// @Description 解析 Ford UK Cars/Vans 页面数据并入库，填充 detail_url 与 trim_detail_link
// @Tags vehicles
// @Produce json
// @Success 200 {object} gin.H
// @Router /api/scrape_all [post]
func (h *VehicleHandler) ScrapeAllVehicles(c *gin.Context) {
    // 读取基础 URL
    baseURL := "https://www.ford.co.uk"

    // 创建车辆爬虫
    vs := scraper.NewVehicleScraper(h.storage, h.logger, baseURL)

    if err := vs.ScrapeAll(); err != nil {
        h.logger.WithError(err).Error("Failed to scrape showroom pages")
        c.JSON(http.StatusInternalServerError, gin.H{
            "code":    500,
            "message": "Failed to scrape showroom pages: " + err.Error(),
        })
        return
    }

    // 简单返回统计
    stats, _ := h.storage.GetCategoryStats()
    c.JSON(http.StatusOK, gin.H{
        "code":    200,
        "message": "Scraped showroom pages successfully",
        "stats":   stats,
    })
}

// mockScrapeTrims 模拟trim抓取过程
func (h *VehicleHandler) mockScrapeTrims(modelName string) error {
	// 检查车型是否存在
	_, err := h.storage.GetVehicleDetailURL(modelName)
	if err != nil {
		return fmt.Errorf("model '%s' not found", modelName)
	}

	// 清理旧数据
	if err := h.storage.DeleteTrimByModel(modelName); err != nil {
		h.logger.WithError(err).Warn("Failed to clean old trim data")
	}

	// 模拟trim数据
	trims := h.getMockTrimData(modelName)

	// 🔥 升级: 使用新的JSON存储方式保存trim和规格信息
	// 创建scraper实例
	trimScraper := scraper.NewTrimScraper(h.storage, h.logger)

	for _, trim := range trims {
		// 使用scraper获取完整规格数据 (Issue #003: 完整的"See Full Specs"内容)
		specs := trimScraper.GetMockSpecsData(trim.TrimName, modelName)

		// 🔥 使用新方法：同时保存trim信息和JSON格式的规格
		if err := h.storage.UpsertTrimWithJSONSpecs(&trim, specs); err != nil {
			h.logger.WithError(err).WithField("trim", trim.TrimName).Error("Failed to save trim with JSON specs")

			// 🔥 如果新方法失败，回退到旧方法以保证兼容性
			h.logger.WithField("trim", trim.TrimName).Warn("Falling back to legacy storage method")

			// 保存基本信息
			if err := h.storage.UpsertTrimInfo(&trim); err != nil {
				h.logger.WithError(err).WithField("trim", trim.TrimName).Error("Failed to save trim info")
			}

			// 保存规格信息
			if err := h.storage.BatchUpsertTrimSpecs(specs); err != nil {
				h.logger.WithError(err).WithField("trim", trim.TrimName).Error("Failed to save trim specs")
			}
		} else {
			h.logger.WithFields(logrus.Fields{
				"trim":        trim.TrimName,
				"specs_count": len(specs),
			}).Info("Successfully saved trim with JSON specs")
		}
	}

	return nil
}

// getMockTrimData 获取模拟trim数据
func (h *VehicleHandler) getMockTrimData(modelName string) []models.TrimInfo {
	var trims []models.TrimInfo

	// 根据不同model提供不同的trim数据
	if strings.Contains(strings.ToLower(modelName), "puma") {
		// Puma的trim配置
		trimsData := []struct {
			name        string
			price       float64
			battery     string
			consumption string
			range_miles string
		}{
			{"Select", 29995.00, "43 kWh Standard Range", "13.1 kWh/100km", "233.6 miles"},
			{"Premium", 31995.00, "43 kWh Standard Range", "13.7 kWh/100km", "226.2 miles"},
			{"Sound Edition", 33995.00, "43 kWh Standard Range", "13.5 kWh/100km", "230.0 miles"},
		}

		for _, data := range trimsData {
			trim := models.TrimInfo{
				ModelName:             modelName,
				TrimName:              data.name,
				TrimDisplayName:       fmt.Sprintf("Ford %s %s", modelName, data.name),
				Doors:                 &[]int{5}[0],
				PriceFrom:             &data.price,
				Currency:              "GBP",
				BatteryCapacity:       data.battery,
				EnergyConsumption:     data.consumption,
				CO2Emissions:          "0 g/km",
				ChargingTime:          "24 min",
				RangeMiles:            data.range_miles,
				SeeFullSpecsAvailable: true,
				ScrapedAt:             time.Now(),
			}

			trims = append(trims, trim)
		}
	} else {
		// 其他车型的通用trim配置
		defaultTrims := []string{"Base", "Mid", "High"}
		for i, trimName := range defaultTrims {
			basePrice := 25000.00 + float64(i*5000)
			trim := models.TrimInfo{
				ModelName:             modelName,
				TrimName:              trimName,
				TrimDisplayName:       fmt.Sprintf("Ford %s %s", modelName, trimName),
				Doors:                 &[]int{5}[0],
				PriceFrom:             &basePrice,
				Currency:              "GBP",
				SeeFullSpecsAvailable: true,
				ScrapedAt:             time.Now(),
			}

			trims = append(trims, trim)
		}
	}

	return trims
}

// getMockSpecsData 获取模拟规格数据
func (h *VehicleHandler) getMockSpecsData(trimName, modelName string) []models.TrimSpecsInfo {
	var specs []models.TrimSpecsInfo

	// 基于trim名称和model名称提供规格数据
	if strings.Contains(strings.ToLower(modelName), "puma") {
		// Puma的详细规格
		commonSpecs := []models.TrimSpecsInfo{
			{TrimName: trimName, ModelName: modelName, SpecCategory: "Performance", SpecName: "CO2 Emissions", SpecValue: "0", SpecUnit: "g/km", DisplayOrder: 1},
			{TrimName: trimName, ModelName: modelName, SpecCategory: "Performance", SpecName: "Battery Type", SpecValue: "Lithium-ion", SpecUnit: "", DisplayOrder: 2},
			{TrimName: trimName, ModelName: modelName, SpecCategory: "Battery", SpecName: "Battery Capacity", SpecValue: "43", SpecUnit: "kWh", DisplayOrder: 3},
			{TrimName: trimName, ModelName: modelName, SpecCategory: "Charging", SpecName: "Fast Charging", SpecValue: "10-80%", SpecUnit: "in 23.2 min", DisplayOrder: 4},
			{TrimName: trimName, ModelName: modelName, SpecCategory: "Dimensions", SpecName: "Doors", SpecValue: "5", SpecUnit: "", DisplayOrder: 6},
			{TrimName: trimName, ModelName: modelName, SpecCategory: "Powertrain", SpecName: "Drive Type", SpecValue: "Front-wheel drive", SpecUnit: "", DisplayOrder: 10},
		}

		// 根据trim添加特定规格
		switch trimName {
		case "Select":
			commonSpecs = append(commonSpecs,
				models.TrimSpecsInfo{TrimName: trimName, ModelName: modelName, SpecCategory: "Performance", SpecName: "Range (WLTP)", SpecValue: "233.6", SpecUnit: "miles", DisplayOrder: 12},
				models.TrimSpecsInfo{TrimName: trimName, ModelName: modelName, SpecCategory: "Features", SpecName: "Alloy Wheels", SpecValue: "17\"", SpecUnit: "", DisplayOrder: 14},
			)
		case "Premium":
			commonSpecs = append(commonSpecs,
				models.TrimSpecsInfo{TrimName: trimName, ModelName: modelName, SpecCategory: "Performance", SpecName: "Range (WLTP)", SpecValue: "226.2", SpecUnit: "miles", DisplayOrder: 12},
				models.TrimSpecsInfo{TrimName: trimName, ModelName: modelName, SpecCategory: "Features", SpecName: "Alloy Wheels", SpecValue: "18\"", SpecUnit: "", DisplayOrder: 14},
				models.TrimSpecsInfo{TrimName: trimName, ModelName: modelName, SpecCategory: "Features", SpecName: "Sound System", SpecValue: "B&O Premium", SpecUnit: "", DisplayOrder: 16},
			)
		case "Sound Edition":
			commonSpecs = append(commonSpecs,
				models.TrimSpecsInfo{TrimName: trimName, ModelName: modelName, SpecCategory: "Performance", SpecName: "Range (WLTP)", SpecValue: "230.0", SpecUnit: "miles", DisplayOrder: 12},
				models.TrimSpecsInfo{TrimName: trimName, ModelName: modelName, SpecCategory: "Features", SpecName: "Sound System", SpecValue: "Ford Collection Premium", SpecUnit: "", DisplayOrder: 14},
			)
		}

		for i := range commonSpecs {
			commonSpecs[i].ScrapedAt = time.Now()
		}

		specs = commonSpecs
	} else {
		// 其他车型的通用规格
		generalSpecs := []models.TrimSpecsInfo{
			{TrimName: trimName, ModelName: modelName, SpecCategory: "Engine", SpecName: "Engine Type", SpecValue: "EcoBoost", SpecUnit: "", DisplayOrder: 1},
			{TrimName: trimName, ModelName: modelName, SpecCategory: "Performance", SpecName: "Fuel Type", SpecValue: "Petrol", SpecUnit: "", DisplayOrder: 2},
			{TrimName: trimName, ModelName: modelName, SpecCategory: "Dimensions", SpecName: "Doors", SpecValue: "5", SpecUnit: "", DisplayOrder: 3},
		}

		for i := range generalSpecs {
			generalSpecs[i].ScrapedAt = time.Now()
		}

		specs = generalSpecs
	}

	return specs
}
